

local JIANG_TBL = {
    [2] = 1,
    [5] = 1,
    [8] = 1
}

local function get_card_type( card_v )
    return math.floor( card_v / 9 )
end

local function get_card_number( card_v )
    return card_v % 9 + 1
end

local function is_jiang( card_v )
    return JIANG_TBL[get_card_number(card_v)]
end

local function is_qingyise(card_dict, extra)
    local card_type
    for _, v in ipairs(extra) do
        local card 
        if type(v.value) == "table" then
            card = v.value[2]
        else
            card = v.value
        end 
        local cur_type = get_card_type(card)
        if not card_type then
            card_type = cur_type
        elseif card_type ~= cur_type then 
            return false
        end
    end
    
    for _,card in pairs(card_dict) do
        local cur_type = get_card_type(card)
        if not card_type then
            card_type = cur_type
        elseif card_type ~= cur_type then 
            return false
        end
    end
    return true
end

DA_HU = 
{
    QI_DUI = 1,
    LONG_QI_DUI = 2,
    QING_QI_DUI = 3,
    QING_LONG_QI_DUI = 4,

    DUIDUI = 5,
    JINGOU_DUIDUI = 6,
    SBLH_DUIDUI = 7,
    JIANG_DUIDUI = 8,
    QING_DUIDUI = 9,
    QING_JINGOU_DUIDUI = 10,
    QING_SBLH_DUIDUI = 11,

    YAOJIU = 12,
    QING_YAOJIU = 13,

    QING_YI_SE = 14
}

DA_HU_FAN =
{
    [DA_HU.QI_DUI] = 3,
    [DA_HU.LONG_QI_DUI] = 5,
    [DA_HU.QING_QI_DUI] = 5,
    [DA_HU.QING_LONG_QI_DUI] = 6,

    [DA_HU.DUIDUI] = 2,
    [DA_HU.JINGOU_DUIDUI] = 2.1,
    [DA_HU.SBLH_DUIDUI] = 6,
    [DA_HU.JIANG_DUIDUI] = 4,
    [DA_HU.QING_DUIDUI] = 4,
    [DA_HU.QING_JINGOU_DUIDUI] = 4.1,
    [DA_HU.QING_SBLH_DUIDUI] = 8,

    [DA_HU.YAOJIU] = 3,
    [DA_HU.QING_YAOJIU] = 5,

    [DA_HU.QING_YI_SE] = 3

}

local function get_card_dict( cardtbl )
    local  ret  = {}
    for _,v in pairs(cardtbl) do
        ret[v] = (ret[v] or 0 ) + 1
    end
    return ret
end

local function get_ext_card_dict( cardtbl )
    local  ret  = {}
    for _,v in pairs(cardtbl) do
        local card 
        if type(v.value) == "table" then
            card = v.value[2]
        else
            card = v.value
        end
        ret[card] = (ret[card] or 0 ) + 1
    end
    return ret
end

--
local function get_qidui_type( cardtbl )

    if #cardtbl < 13 then
        return nil
    end

    local ret = {}
    local card_dic = get_card_dict(cardtbl)
    local now_tp = DA_HU.QI_DUI
    ret[now_tp] =1
    for _,v in pairs(card_dic) do
        if v ~= 2 and v ~= 4 then
            return nil
        end
        if v == 4 then
            now_tp = DA_HU.LONG_QI_DUI
            ret[ now_tp ] = 1
        end
    end

    if is_qingyise(cardtbl, {}) then
        if ret[DA_HU.LONG_QI_DUI] then
            now_tp = DA_HU.QING_LONG_QI_DUI
            ret[ now_tp ] = 1
        else
            now_tp = DA_HU.QING_QI_DUI
            ret[ now_tp ] = 1
        end
    end
    return ret
end

local function get_duidui_type( cardtbl, extra )
    local card_dic = get_card_dict(cardtbl)
    local now_tp = DA_HU.DUIDUI
    for _,v in pairs(card_dic) do
        if v == 1 then
            return nil
        end
    end

    local ret = {}
    ret[now_tp] = 1
    if table.length(cardtbl) == 2 then
        now_tp = DA_HU.JINGOU_DUIDUI
        ret[ now_tp ] = 1
    end

    --check jiang
    local is_all_jiang = true
    for v,_ in pairs(card_dic) do
        if not is_jiang(v) then
            is_all_jiang = false
            break
        end
    end
    if is_all_jiang then
        for _,v in pairs(extra) do
            local card 
            if type(v.value) == "table" then
                card = v.value[2]
            else
                card = v.value
            end
            if not is_jiang(card) then
                is_all_jiang = false
                break
            end
        end        
    end
    if is_all_jiang then
        now_tp = DA_HU.JIANG_DUIDUI
        ret[ now_tp ] = 1
    end

    local ext_dic = get_ext_card_dict(extra)
    if table.length(extra)==16 then
        local is_all_4 = true
        for _,v in pairs(ext_dic) do
            if v ~= 4 then
                is_all_4 = false
                break
            end
        end
        if is_all_4 then
            now_tp = DA_HU.SBLH_DUIDUI
            ret[ now_tp ] = 1
        end
    end

    if is_qingyise(cardtbl, extra) then
        if ret[DA_HU.DUIDUI] then
            ret[DA_HU.QING_DUIDUI] = 1
        end
        if ret[DA_HU.JINGOU_DUIDUI] then
            ret[DA_HU.QING_JINGOU_DUIDUI] = 1
        end
        if ret[DA_HU.SBLH_DUIDUI] then
            ret[DA_HU.QING_SBLH_DUIDUI] = 1
        end 
    end

    return ret
end

local function get_yaojiu_type( cardtbl, extra )
   local card_dic = get_card_dict(cardtbl)
   local  ret = {}
   local now_tp
   for card,num in pairs(card_dic) do
        if num == 1 or ( get_card_number(card) ~= 1 and get_card_number(card) ~= 9) then
            return nil
        end
        now_tp = DA_HU.YAOJIU
        ret[now_tp] = 1
   end

   if is_qingyise(cardtbl, extra) and ret[DA_HU.YAOJIU] then
        now_tp = DA_HU.QING_YAOJIU
        ret[now_tp] = 1 
   end

   return ret
end 

local function get_gen_count( cardtbl, hu_tp  )
    if hu_tp == DA_HU.LONG_QI_DUI or hu_tp == DA_HU.QING_LONG_QI_DUI then
        return 0
    end
    
    local card_dic = get_card_dict(cardtbl)
    local gen_count = 0
    for card,num in pairs(card_dic) do
        if num == 4 then
            gen_count = gen_count + 1
        end
    end
    return gen_count
end

local function get_hu_type( cardtbl, extra )
    local ret = get_qidui_type(cardtbl) or {}
    local ret_duidui = get_duidui_type(cardtbl, extra) or {}
    local ret_yaojiu = get_yaojiu_type(cardtbl, extra) or {}
    local ret_tbl = table.merge(ret, ret_duidui)
    local ret_tbl = table.merge(ret_tbl, ret_yaojiu)

    if is_qingyise(cardtbl,extra) then
        ret_tbl[DA_HU.QING_YI_SE] = 1
    end
    --print("ret_duidui; %s", table.dump( ret_tbl) )

    local max_tp = 0
    local max_fan = 0
    for tp,_ in pairs(ret_tbl) do
        if DA_HU_FAN[tp] > max_fan then
            max_tp = math.floor(tp)
            max_fan = DA_HU_FAN[tp]
        end
    end

    return math.floor(max_tp)
end

--[[
local function get_dahu_fan( cardtbl, extra )
    local tp = get_hu_type(cardtbl, extra)
    local gen_count = get_gen_count(cardtbl, tp)
    return DA_HU_FAN[tp] + gen_count
end
]]

local function get_hu_fan_by_type( cardtbl, tp )
    if tp == 0 then
        return 0
    end
    if not DA_HU_FAN[tp] then
        return 0 
    end

    local gen_count = get_gen_count(cardtbl, tp)
    return math.floor(DA_HU_FAN[tp]) + gen_count
end

return {
    get_hu_type = get_hu_type,
    get_hu_fan = get_hu_fan_by_type,
    DA_HU = DA_HU,
    DA_HU_FAN = DA_HU_FAN
}
